import { type MappingAlgorithm, theme as Theme, type ThemeConfig } from 'antd'
import { create } from 'zustand'
import i18n from '@/locales'
import { AliasToken } from 'antd/es/theme/internal'
import { debounce } from '@/utils/timer'

export type ThemeName = 'dark' | 'light' | undefined

export type LangName = 'zh-CN' | 'en-US' | undefined

type State = {
  isExpandedSidebar: boolean

  langName: LangName

  themeToken: Partial<AliasToken>
  themeName: ThemeName

  isMobile: boolean
}

type Actions = {
  setExpandSidebar: (expanded: boolean) => void

  setLangName: (lang?: LangName)=>void
  getLangName: () => LangName

  setThemeColor: (color: string) => void
  getThemeColor: () => string
  setThemeName: (name?: ThemeName) => void
  getThemeName: () => ThemeName
  getThemeConfig: () => ThemeConfig
}

const ENV_EXPANDED_SIDBAR = 'env:is-expanded-sidebar'
const ENV_LANG_NAME = 'env:lang-name'
const ENV_THEME_TOKEN = 'env:theme-token'
const ENV_THEME_NAME = 'env:theme-name'

const DEFAULT_THEME_COLOR = '#1677FF'

const themeNameToAlgorithm = function (name: string): MappingAlgorithm {
  switch(name){
    case 'dark': return Theme.darkAlgorithm
    case 'light': return Theme.defaultAlgorithm
    default: return Theme.defaultAlgorithm
  }
}


export const useEnvStore = create<State & Actions>((set, get) => {

  /**
   * 判断是否为移动端
   */
  const getIsMobile = function () {
    return window.innerWidth <= 768
  }

  /**
   * 监听屏幕变化
   */
  window.addEventListener("resize", debounce(() => {
    set({isMobile: getIsMobile()})
  }))

  /**
   * 展开侧边栏
   * @param expanded 'true':展开 | 'false':缩小
   */
  const setExpandSidebar = function (expanded: boolean) {
    if(expanded){
      sessionStorage.removeItem(ENV_EXPANDED_SIDBAR)
    }else{
      sessionStorage.setItem(ENV_EXPANDED_SIDBAR, 'false')
    }
    set({ isExpandedSidebar: expanded })
  }

  /**
   * 获取当前LangName（识别跟随系统）
   */
  const getLangName = function () {
    const {langName} = get()
    if(langName){
      return langName
    }
    switch(navigator.language.slice(0, 2)){
      case 'en': return 'en-US'
      case 'zh': 
      default: return 'zh-CN'
    }
  }

  /**
   * 切换语言
   */
  const setLangName = function (lang?: LangName) {
    if(lang){
      sessionStorage.setItem(ENV_LANG_NAME, lang)
    }else{
      sessionStorage.removeItem(ENV_LANG_NAME)
    }
    set({ langName: lang })
    i18n.changeLanguage(lang ?? getLangName())
  }

  /**
   * 修改主题颜色(setThemeToken)
   */
  const setThemeColor = function (color: string) {
    const token = {
      "colorPrimary": color,
      "colorInfo": color,
    }
    localStorage.setItem(ENV_THEME_TOKEN, JSON.stringify(token))
    set({themeToken: token})
  }

  /**
   * 获取主题颜色
   */
  const getThemeColor = function () {
    return get()?.themeToken.colorPrimary ?? DEFAULT_THEME_COLOR
  }

  /**
   * 获取当前系统主题名字
   */
  const getSysThemeName = function () {
    return window.matchMedia("(prefers-color-scheme: dark)").matches ? 'dark' : 'light'
  }

  /**
   * 获取当前主题名字（自动识别跟随系统）
   */
  const getThemeName = function () {
    return get()?.themeName ?? getSysThemeName()
  }

  /**
   * 设置主题名字
   */
  const setThemeName = function (name?: ThemeName) {
    if(name){
      localStorage.setItem(ENV_THEME_NAME, name)
    }else{
      localStorage.removeItem(ENV_THEME_NAME)
    }
    set(({themeToken}) => ({ 
      themeName: name,
      themeToken: {
        ...themeToken,
        algorithm: themeNameToAlgorithm(getThemeName())
      }
    }))
  }

  /**
   * 获取主题配置
   */
  const getThemeConfig = function (): ThemeConfig {
    return {
      token: get().themeToken,
      algorithm: themeNameToAlgorithm(getThemeName()),
    } 
  }

  const themeTokenStr = localStorage.getItem(ENV_THEME_TOKEN)
  const themeToken = themeTokenStr ? JSON.parse(themeTokenStr) : undefined

  const lang = sessionStorage.getItem(ENV_LANG_NAME) as LangName ?? undefined
  setLangName(lang)

  return {
    /* Sidebar */
    isExpandedSidebar: !sessionStorage.getItem(ENV_EXPANDED_SIDBAR),
    setExpandSidebar,

    /* Language */
    langName: lang,
    setLangName,
    getLangName,

    /* Theme */
    themeName: localStorage.getItem(ENV_THEME_NAME) as ThemeName ?? undefined,
    themeToken: themeToken ?? {
      "colorPrimary": DEFAULT_THEME_COLOR,
      "colorInfo": DEFAULT_THEME_COLOR,
      // "wireframe": false,
    },
    setThemeColor,
    getThemeColor,
    setThemeName,
    getThemeName,
    getThemeConfig,

    /* Screen */
    isMobile: getIsMobile()
  }
})

